home *** CD-ROM | disk | FTP | other *** search
- /*
- * Quickdraw 3D sample code
- *
- * This file shows how to implement a simple custom attribute as a plug-in.
- *
- * Nick Thompson, nickt@apple.com, November 1996
- *
- * Please send technical questions that you may have about this code
- * to devsupport@apple.com
- *
- * Based on attributelib. For more information about the basic principles
- * of this, check the article in develop, plugins in the form of shared
- * libraries were just a twinkle in kent's eye then. The main difference
- * is in the way these puppies get registered, and in the name sapce.
- *
- * This sample code has minimal error checking. More should be added if this
- * code is used in a production quality product.
- *
- * Revision History:
- * 8/12/97 RDD Changed register and unregister functions and fixed
- * CopyReplace method.
- */
-
- #include "QD3D.h"
- #include "QD3DExtension.h"
- #include "QD3DGeometry.h"
- #include "QD3DIO.h"
- #include "QD3DSet.h"
- #include "QD3DString.h"
- #include "QD3DView.h"
-
- #include <Errors.h>
-
- #include <string.h>
- #include "NameAttribute.h"
-
-
- /******************************************************************************
- **
- ** Globals
- **
- *****************************************************************************/
-
- static TQ3XObjectClass pNameAttributeClass = NULL;
-
- static unsigned long pSharedLibrary = 0;
- static const short pMajorVersion = 1 ;
- static const short pMinorVersion = 5 ;
-
- /******************************************************************************
- **
- ** Function prototypes for functions local to this file
- **
- *****************************************************************************/
-
- static TQ3Status NameAttribute_Traverse(
- TQ3Object unused,
- TQ3StringObject *stringObject,
- TQ3ViewObject view) ;
-
- static TQ3Status NameAttribute_ReadData(
- TQ3SetObject attributeSet,
- TQ3FileObject file) ;
-
- static TQ3Status NameAttribute_CopyAdd(
- TQ3StringObject *src,
- TQ3StringObject *dst) ;
-
- static TQ3Status NameAttribute_CopyReplace(
- TQ3StringObject *src,
- TQ3StringObject *dst) ;
-
- static TQ3Status NameAttribute_Delete(
- TQ3StringObject *stringObject) ;
-
- static TQ3XFunctionPointer NameAttribute_MetaHandler(
- TQ3XMethodType methodType) ;
-
-
-
- /*===========================================================================*\
- *
- * Routine: NameAttribute_SetName()
- *
- * Comments: Utility function to add a name on an shape object, geometry
- * object, or attribute set.
- *
- \*===========================================================================*/
-
- TQ3Status NameAttribute_SetName(
- TQ3Object object,
- char *name)
- {
- TQ3StringObject string = NULL;
- TQ3AttributeSet set = NULL;
- TQ3Status status = kQ3Success;
- TQ3ElementType myElementType ;
-
- /*
- * NOTE: You cannot just use the type as it was registered,
- * so you have two options: the first is to save a reference
- * to the element type that we got back from the register function
- * the second is to use the global class to get the type. Since
- * we already need to keep the class global, that's what I decided
- * to do here. (This code is not optimal)
- */
- Q3XObjectClass_GetType( pNameAttributeClass, &myElementType) ;
-
- if( Q3Object_IsType(object, kQ3SharedTypeShape) == kQ3True ) {
-
- string = Q3CString_New(name);
-
- if( string == NULL) {
- status = kQ3Failure;
- goto cleanExit;
- }
-
- if( Q3Object_IsType(object, kQ3ShapeTypeGeometry) == kQ3True ) {
-
- Q3Geometry_GetAttributeSet(object, &set);
-
- if( set == NULL ) {
- set = Q3AttributeSet_New();
- if( set == NULL ) {
- status = kQ3Failure;
- goto cleanExit;
- }
- Q3Geometry_SetAttributeSet(object, set);
- }
- } else {
- Q3Shape_GetSet(object, &set);
-
- if( set == NULL ) {
- set = Q3Set_New();
- if( set == NULL ) {
- status = kQ3Failure;
- goto cleanExit;
- }
- Q3Shape_SetSet(object, set);
- }
- }
-
- if( Q3Set_Add(set, myElementType, &string) == kQ3Failure ) {
- status = kQ3Failure;
- goto cleanExit;
- }
- } else if( Q3Object_IsType(object, kQ3SharedTypeSet) == kQ3True ) {
- string = Q3CString_New(name);
-
- if( string == NULL) {
- status = kQ3Failure;
- goto cleanExit;
- }
-
- if( Q3AttributeSet_Add(object, myElementType, &string) == kQ3Failure ) {
- status = kQ3Failure;
- goto cleanExit;
- }
- } else
- status = kQ3Failure;
-
- cleanExit:
- if( string )
- Q3Object_Dispose(string);
- if( set )
- Q3Object_Dispose(set);
- return status;
- }
-
- /*===========================================================================*\
- *
- * Routine: NameAttribute_GetName()
- *
- * Comments: Utility function to get a name from a shape object, geometry
- * object, or an attribute set.
- *
- \*===========================================================================*/
-
- TQ3Status NameAttribute_GetName(
- TQ3Object object,
- char *name)
- {
- TQ3StringObject string = NULL;
- TQ3AttributeSet set = NULL;
- TQ3Status status = kQ3Success;
- char *nameString = NULL ;
- TQ3ElementType myElementType ;
-
- /*
- * NOTE: You cannot just use the type as it was registered,
- * so you have two options: the first is to save a reference
- * to the element type that we got back from the register function
- * the second is to use the global class to get the type. Since
- * we already need to keep the class global, that's what I decided
- * to do here. Set up the element type:
- */
- Q3XObjectClass_GetType( pNameAttributeClass, &myElementType) ;
-
- if( Q3Object_IsType(object, kQ3SharedTypeShape) == kQ3True ) {
-
- if( Q3Object_IsType(object, kQ3ShapeTypeGeometry) == kQ3True ) {
-
- Q3Geometry_GetAttributeSet(object, &set);
-
- if( set == NULL ) {
- status = kQ3Failure;
- goto cleanExit;
- }
-
- }
- else
- {
- Q3Shape_GetSet(object, &set);
- }
-
- if( Q3Set_Contains ( set, myElementType ) == kQ3True ) {
- status = Q3Set_Get ( set, myElementType, &string ) ;
- if( string == NULL || status == kQ3Failure ) {
- status = kQ3Failure;
- goto cleanExit;
- }
- }
-
- }
- else if( Q3Object_IsType(object, kQ3SharedTypeSet) == kQ3True ) {
-
- if( Q3AttributeSet_Get(object, myElementType, &string) == kQ3Failure ) {
- status = kQ3Failure;
- goto cleanExit;
- }
-
- } else
- status = kQ3Failure;
-
- if( status != kQ3Failure && string != NULL )
- {
- /* get the string from the CString object */
- status = Q3CString_GetString ( string, &nameString ) ;
- strcpy( name, nameString ) ;
- status = Q3CString_EmptyData(&nameString);
- }
- else
- {
- *name = NULL ;
- }
-
- cleanExit:
- if( string )
- Q3Object_Dispose(string);
-
- if( set )
- Q3Object_Dispose(set);
- return status;
- }
-
-
- /*===========================================================================*\
- *
- * Routine: NameAttributeClassRegister()
- *
- * Comments: Registers the Name attribute class.
- *
- \*===========================================================================*/
-
- TQ3Status NameAttribute_Register( void )
- {
- TQ3ElementType myElementType = kQ3ObjectTypeInvalid ; /* discarded */
-
- /*
- * Register the new name element class. NOTE: this will change myElementType
- * to be a unique type. This helps to prevent namespace clashes, but you MUST
- * remember to use what you are passed back when accessing the elements of a set.
- *
- * You can either store the value returned in myElementType or use the global
- * pNameAttributeClass. In this sample we use the latter approach. Now that we
- * have a reference to the class around we can use that to get the type for
- * the calls that need the type using the following API call:
- *
- * Q3XObjectClass_GetType( pNameAttributeClass, &myElementType) ;
- */
-
- pNameAttributeClass =
- Q3XElementClass_Register(
- &myElementType,
- kElementTypeNameString,
- sizeof(TQ3StringObject),
- NameAttribute_MetaHandler );
-
- if (pNameAttributeClass == NULL)
- return kQ3Failure;
-
- return kQ3Success;
- }
-
-
- /* Name attribute CFM init and termination routines */
-
- OSErr NameAttribute_ConnectionInitializationRoutine(InitBlockPtr initBlock)
- {
- TQ3Status theStatus;
- TQ3XSharedLibraryInfo sharedLibraryInfo;
- OSErr osErr;
-
- /*
- * Register this custom attribute/element with QuickDraw 3D using the
- * callback Q3XSharedLibrary_Register which is passed the register function
- * and the closureID (_not_ the connectionID).
- */
- sharedLibraryInfo.registerFunction = NameAttribute_Register;
- sharedLibraryInfo.sharedLibrary = (unsigned long)initBlock->connectionID;
- theStatus = Q3XSharedLibrary_Register(&sharedLibraryInfo);
-
- if (theStatus == kQ3Success) {
- pSharedLibrary = (unsigned long)initBlock->connectionID;
- osErr = noErr;
- }
- else {
- osErr = fragMgrInitErr; /* ...or some other meaningfull error */
- }
-
- return osErr;
- }
-
-
-
- void NameAttribute_ConnectionTerminationRoutine (void)
- {
- TQ3Status theStatus ;
-
- if( pSharedLibrary != NULL ) {
- theStatus = Q3XSharedLibrary_Unregister(pSharedLibrary);
- pSharedLibrary = NULL;
- }
-
- theStatus = NameAttribute_Unregister() ;
- }
-
-
- /*
- * Static Functions
- */
-
- static TQ3Status NameAttribute_Traverse(
- TQ3Object unused,
- TQ3StringObject *stringObject,
- TQ3ViewObject view)
- {
- (void) unused;
-
- if (stringObject == NULL || *stringObject == NULL)
- return kQ3Success;
-
- if (Q3XView_SubmitWriteData(view, 0, NULL, NULL) == kQ3Failure) {
- return kQ3Failure;
- }
-
- if (Q3Object_Submit( *stringObject, view) == kQ3Failure) {
- return kQ3Failure;
- }
-
- return kQ3Success;
- }
-
- static TQ3Status NameAttribute_ReadData(
- TQ3SetObject attributeSet,
- TQ3FileObject file)
- {
- TQ3StringObject stringObject;
- TQ3Status status;
-
- TQ3ElementType myElementType ;
-
- /*
- * NOTE: You cannot just use the type as it was registered,
- * so you have two options: the first is to save a reference
- * to the element type that we got back from the register function
- * the second is to use the global class to get the type. Since
- * we already need to keep the class global, that's what I decided
- * to do here.
- */
- Q3XObjectClass_GetType( pNameAttributeClass, &myElementType) ;
-
- stringObject = Q3File_ReadObject(file);
-
- status = Q3Set_Add(attributeSet, myElementType, &stringObject);
-
- Q3Object_Dispose(stringObject);
-
- /*
- * Note that the string object has a reference count of 1,
- * which will be taken care of in the dispose
- */
- return status;
- }
-
- static TQ3Status NameAttribute_CopyAdd(
- TQ3StringObject *src,
- TQ3StringObject *dst)
- {
- *dst = Q3Shared_GetReference(*src);
-
- return (*dst != NULL) ? kQ3Success : kQ3Failure;
- }
-
- static TQ3Status NameAttribute_CopyReplace(
- TQ3StringObject *src,
- TQ3StringObject *dst)
- {
- TQ3StringObject tempString;
-
- /*
- * It is always good form to get a reference first,
- * in case src and dst point to the same object
- */
-
- tempString = Q3Shared_GetReference(*src);
- if (tempString == NULL)
- return kQ3Failure;
-
- if( *dst )
- Q3Object_Dispose( *dst );
-
- *dst = tempString;
-
- return kQ3Success;
- }
-
- static TQ3Status NameAttribute_Delete(
- TQ3StringObject *stringObject)
- {
- if (*stringObject != NULL) {
- Q3Object_Dispose(*stringObject);
- *stringObject = NULL;
- }
-
- return kQ3Success;
- }
-
- TQ3Status NameAttribute_Unregister(
- void)
- {
- TQ3Status returnVal = kQ3Failure ;
-
- if ( pNameAttributeClass != NULL )
- {
- /*
- * QuickDraw 3D unregisters this object together with all
- * other registered objects in the system on Q3Exit.
- */
- pNameAttributeClass = NULL ;
- returnVal = kQ3Success ;
- }
-
- return returnVal ;
- }
-
-
-
- /*
- * NameAttribute_MetaHandler
- */
- static TQ3XFunctionPointer NameAttribute_MetaHandler(
- TQ3XMethodType methodType)
- {
- switch (methodType)
- {
- case kQ3XMethodTypeObjectClassVersion:
- return (TQ3XFunctionPointer)
- Q3_OBJECT_CLASS_VERSION(pMajorVersion, pMinorVersion);
-
- case kQ3XMethodTypeObjectTraverse:
- return (TQ3XFunctionPointer) NameAttribute_Traverse;
-
- case kQ3XMethodTypeObjectReadData:
- return (TQ3XFunctionPointer) NameAttribute_ReadData;
-
- case kQ3XMethodTypeElementCopyAdd:
- case kQ3XMethodTypeElementCopyGet:
- case kQ3XMethodTypeElementCopyDuplicate:
- return (TQ3XFunctionPointer) NameAttribute_CopyAdd;
-
- case kQ3XMethodTypeElementCopyReplace:
- return (TQ3XFunctionPointer) NameAttribute_CopyReplace;
-
- case kQ3XMethodTypeElementDelete:
- return (TQ3XFunctionPointer) NameAttribute_Delete;
-
- default:
- return (TQ3XFunctionPointer) NULL;
- }
- }
-
-